modal 后的层级结构与storyboard-的-dismiss

场景

界面 A 被一个 Nav 所包含,界面 B 也被另一个 nav 所包含.
通过界面 A, 我们 modal 出一个界面 B.

效果:

首先讲 storyboard 的 dismiss

问题所在

Q: 在 storyboard 中,无法直接拖线条的方式拖出 dismiss 效果.
A: 因为:storyboard 中得线条其实就是一条条的 segue.

Storyboard Segue 设计就是单向跳转。

每个 segue 都会创建一个目标控制器, 由调用 segue 的控制器作为来源控制器.就算表面上你看起来依然是由 A->B,再 B->A .但是这时候的 A 已经不是原来的 A 了,而是重新创建了一个 A.

想要实现 storyboard 中的 dismiss, 方法如下:

方法一:

写一个自定义 segue 能做到,但任何时候都不应该用 segue 来做 pop 或 dismiss 。原因是会创建一个新的控制器,而非原来的.

方法二:

在界面 B 实现方法:

1
2
3
- (IBAction)back:(id)sender {
[self dismissViewControllerAnimated:YES completion:nil];
}

方法三:

想要在 B 界面点一个按钮,实现 B–>A, 那么:

一. 在 A 里面实现一个空方法

1
2
3
- (IBAction)unwindSegueToRedViewController:(UIStoryboardSegue *)segue {
}

二. 在storyboard 中 B 上,添加一个按钮 button

三. 在storyboard 中 A 上,点击,将出现的unwindSegueXXX方法和界面 B 的 按钮 button 相连即可

modal 后的视图层级

场景:在界面 A–ViewController中,点击按钮, modal 出界面 B –MyVC

在界面 A 打印下当前 Nav 的子控制器们,
在界面 B 打印下当前 Nav 的子控制器们及 appdelegaterootViewController 的子控制器们
并且改变 nav 的颜色.

效果:

code:

一. 在界面 A:

1
2
3
4
5
6
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
NSLog(@"%@",[self.navigationController viewControllers]);
}

打印结果:

ViewController: 0x7fdac9631de0

二. 在界面 B:

1
2
3
4
5
6
7
8
9
10
11
12
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
NSLog(@"%@",[self.navigationController viewControllers]);
UINavigationController *nav = (UINavigationController *)[UIApplication sharedApplication].keyWindow.rootViewController;
NSLog(@"%@",[nav viewControllers]);
[nav.navigationBar setBackgroundColor:[UIColor orangeColor]];
}

打印结果:

第一个 NSLOG:

MyVC: 0x7fdac957c8e0

第二个 NSLOG:

ViewController: 0x7fdac9631de0

结论

可以看到,有界面 A 控制器 modal 出来的界面 B,[UIApplication sharedApplication].keyWindow.rootViewController指向的依然是界面 A, 虽然说我们用Xcode层级结构看不见.

但是咱们用 self.navigationController表示的却是当前控制器 B 的navigationController


原创文章,转载请注明地址: https://kevinmky.github.io